Tarea 1
- Nombre: Mateo Orozco Baldovino
- Especializacion en Estadistica Aplicada UTB
- La informacion puede ser encontrada en el siguiente repositorio https://github.com/TheMaorba/DataMining/tree/main/Tarea1
Punto 1:¶
# Importando librerias para analizar los datos
import numpy as np
import matplotlib.pyplot as plt
import cv2 as cv
%matplotlib inline
img = cv.imread('D:\Documentos\Especialidad\DataMining\Tarea1\imagenpajaros.jpg')
print("The shape of image is =", np.shape(img))
The shape of image is = (1365, 2048, 3)
plt.figure(figsize=(8,9))
plt.imshow(img)
plt.show()
from skimage import io, color
img2=cv.cvtColor(img,cv.COLOR_BGR2RGB)
plt.figure(figsize=(8,9))
plt.imshow(img2)
plt.show()
img3=cv.cvtColor(img2,cv.COLOR_BGR2GRAY)
plt.figure(figsize=(8,9))
plt.imshow(img3)
plt.show()
r,g,b=cv.split(img2)
plt.figure(figsize=(28,19))
plt.subplot(131)
im=plt.imshow(b,cmap="Blues")
plt.colorbar(im,fraction=0.029, pad=0.04)
plt.subplot(132)
im=plt.imshow(r,cmap="Reds")
plt.colorbar(im,fraction=0.029, pad=0.04)
plt.subplot(133)
im=plt.imshow(g,cmap="Greens")
plt.colorbar(im,fraction=0.029, pad=0.04)
plt.show()
plt.figure(figsize=(8,6))
plt.hist(b.ravel(),bins=256,range=(0,256),color='b',label='blue')
plt.hist(g.ravel(),bins=256,range=(0,256),color='g',label='green')
plt.hist(r.ravel(),bins=256,range=(0,256),color='r',label='red')
plt.legend()
plt.show()
Canal rojo La distribución roja se extiende desde valores bajos pero presenta un pico muy pronunciado alrededor de intensidades cercanas a 140‑160, con una caída progresiva hacia la derecha, lo que indica que la mayoría de los píxeles tienen niveles de rojo medios y relativamente parecidos entre sí. Esto concuerda con la menor varianza y coeficiente de variación que observaste, lo que hace que el canal rojo sea el más uniforme en la imagen.
Canal verde El canal verde aparece desplazado a la derecha respecto al azul y bastante solapado con la parte alta del rojo, con máximos alrededor de 150‑180 y una cola que se extiende hacia valores más bajos. Esto refleja que buena parte de la imagen tiene verdes intensos o medios, pero con más dispersión que el rojo, consistente con su asimetría negativa más marcada.
Canal azul El azul tiene un comportamiento distinto: concentra muchos píxeles en intensidades bajas‑medias (aprox. 0‑120), con un pico notable cerca de 0 y luego una subida progresiva y más plana sin un máximo tan agudo como el rojo. Esto indica que hay abundancia de zonas muy oscuras en azul y una variación amplia, lo que se refleja en su coeficiente de variación más alto y en el hecho de que aporte gran parte del contraste cromático de la imagen.
# Calcule para cada arreglo las medidas de tendencia central, las medidas de dispersión y las medidas de simetría correspondientes, también las medidas de variabilidad o coeficiente de variabilidad o coeficiente de Pearson. Diga si las medidas son robustas o no.
def calcular_estadisticas(arreglo, nombre_color):
media = np.mean(arreglo)
mediana = np.median(arreglo)
moda = np.bincount(arreglo.ravel()).argmax()
varianza = np.var(arreglo)
desviacion_std = np.std(arreglo)
asimetria = (3 * (media - mediana)) / desviacion_std if desviacion_std != 0 else 0
coef_variacion = (desviacion_std / media) * 100 if media != 0 else 0
print(f"Estadísticas para el canal {nombre_color}:")
print(f"Media: {media}")
print(f"Mediana: {mediana}")
print(f"Moda: {moda}")
print(f"Varianza: {varianza}")
print(f"Desviación estándar: {desviacion_std}")
print(f"Asimetría (Coef. de Pearson): {asimetria}")
print(f"Coeficiente de variación: {coef_variacion}%")
print()
# Separar canales
b, g, r = cv.split(img)
# Llamar la función para cada canal
calcular_estadisticas(b, "Azul")
calcular_estadisticas(g, "Verde")
calcular_estadisticas(r, "Rojo")
Estadísticas para el canal Azul: Media: 101.71976443550705 Mediana: 102.0 Moda: 0 Varianza: 2455.638718818396 Desviación estándar: 49.55440160892265 Asimetría (Coef. de Pearson): -0.016965328329733857 Coeficiente de variación: 48.71659100266735% Estadísticas para el canal Verde: Media: 144.99946136167767 Mediana: 159.0 Moda: 163 Varianza: 2161.1804435478466 Desviación estándar: 46.48849797044261 Asimetría (Coef. de Pearson): -0.903484039034163 Coeficiente de variación: 32.06115218213437% Estadísticas para el canal Rojo: Media: 140.94886526860097 Mediana: 147.0 Moda: 149 Varianza: 1566.2797753570271 Desviación estándar: 39.576252669461105 Asimetría (Coef. de Pearson): -0.45869436770109145 Coeficiente de variación: 28.078447168795666%
Tendencia central (brillo por canal): El canal Azul tiene una media/mediana mucho más baja (media ≈ 101.7, mediana = 102) que Verde (media ≈ 145.0, mediana = 159) y Rojo (media ≈ 140.9, mediana = 147), lo que sugiere que la imagen contiene menos intensidad azul promedio y está más “cargada” hacia componentes verdes y rojas.
Forma de la distribución (asimetría): Los tres canales presentan asimetría negativa (Azul ≈ -0.017 casi simétrica, Verde ≈ -0.903 marcada, Rojo ≈ -0.459 moderada), indicando que hay una cola hacia valores bajos; esto es especialmente fuerte en Verde, donde la mediana (159) está bastante por encima de la media (~145), señal de presencia relevante de píxeles con intensidades verdes bajas que “jalan” la media hacia abajo.
Dispersión y estabilidad relativa (variabilidad): En términos absolutos, Azul es el más disperso (DE ≈ 49.55, var ≈ 2455.64), pero en términos relativos (coeficiente de variación) también es el más inestable (CV ≈ 48.7%) frente a Verde (CV ≈ 32.1%) y Rojo (CV ≈ 28.1%); esto significa que el canal azul varía mucho más respecto a su propio promedio, mientras que rojo es el más consistente.
# Punto 4
def clasificar_intensidad(canal):
# Crear un arreglo vacío del mismo tamaño para guardar las categorías
categorias = np.empty(canal.shape, dtype=object)
# Aplicar las reglas
categorias[canal <= 85] = "Oscuro"
categorias[(canal > 85) & (canal <= 170)] = "Medio"
categorias[canal > 170] = "Claro"
return categorias
# Separar canales RGB
b, g, r = cv.split(img2) # ya tienes img2 en formato RGB en tu notebook
# Clasificar cada canal
b_cat = clasificar_intensidad(b)
g_cat = clasificar_intensidad(g)
r_cat = clasificar_intensidad(r)
print("Ejemplo de canal Azul categorizado:")
print(b_cat)
print("Ejemplo de canal Verde categorizado:")
print(g_cat)
print("Ejemplo de canal Rojo categorizado:")
print(r_cat)
Ejemplo de canal Azul categorizado: [['Medio' 'Medio' 'Medio' ... 'Medio' 'Medio' 'Medio'] ['Medio' 'Medio' 'Medio' ... 'Medio' 'Medio' 'Medio'] ['Medio' 'Medio' 'Medio' ... 'Medio' 'Medio' 'Medio'] ... ['Claro' 'Claro' 'Claro' ... 'Medio' 'Medio' 'Medio'] ['Claro' 'Claro' 'Claro' ... 'Medio' 'Medio' 'Medio'] ['Medio' 'Claro' 'Claro' ... 'Medio' 'Medio' 'Medio']] Ejemplo de canal Verde categorizado: [['Medio' 'Medio' 'Medio' ... 'Medio' 'Medio' 'Medio'] ['Medio' 'Medio' 'Medio' ... 'Medio' 'Medio' 'Medio'] ['Medio' 'Medio' 'Medio' ... 'Medio' 'Medio' 'Medio'] ... ['Medio' 'Medio' 'Claro' ... 'Medio' 'Medio' 'Medio'] ['Medio' 'Medio' 'Claro' ... 'Medio' 'Medio' 'Medio'] ['Medio' 'Medio' 'Medio' ... 'Medio' 'Medio' 'Medio']] Ejemplo de canal Rojo categorizado: [['Medio' 'Medio' 'Medio' ... 'Oscuro' 'Oscuro' 'Oscuro'] ['Medio' 'Medio' 'Medio' ... 'Oscuro' 'Oscuro' 'Oscuro'] ['Medio' 'Medio' 'Medio' ... 'Oscuro' 'Oscuro' 'Oscuro'] ... ['Medio' 'Medio' 'Claro' ... 'Medio' 'Medio' 'Medio'] ['Medio' 'Medio' 'Medio' ... 'Medio' 'Medio' 'Medio'] ['Medio' 'Medio' 'Medio' ... 'Medio' 'Medio' 'Medio']]
# Ahora suponga que la escala de cada color, la cual es un número que va en el intervalo [0,255] usted la divide en [”Claro”, ”Medio”, ”Oscuro”], bajo un criterio que usted elabore. Construya un nuevo arreglo (para cada canal) con estos datos.
def categorizar_intensidad(canal):
categorias = np.empty(canal.shape, dtype=object)
categorias[canal < 85] = 'Oscuro'
categorias[(canal >= 85) & (canal < 170)] = 'Medio'
categorias[canal >= 170] = 'Claro'
return categorias
categorias_r = categorizar_intensidad(r)
categorias_g = categorizar_intensidad(g)
categorias_b = categorizar_intensidad(b)
# Función para graficar y analizar cada canal
def graficos_y_analisis(categorias, nombre_canal):
# Contar categorías
valores, conteo = np.unique(categorias, return_counts=True)
# ==== GRÁFICO DE TORTA ====
plt.figure(figsize=(6,6))
plt.pie(conteo, labels=valores, autopct='%1.1f%%')
plt.title(f"Distribución de intensidades - Canal {nombre_canal}")
plt.show()
# ==== GRÁFICO DE BARRAS ====
plt.figure(figsize=(7,5))
plt.bar(valores, conteo)
plt.title(f"Conteo de intensidades - Canal {nombre_canal}")
plt.xlabel("Categoría")
plt.ylabel("Cantidad de píxeles")
plt.show()
# ==== INTERPRETACIÓN AUTOMÁTICA ====
total = conteo.sum()
porcentajes = conteo / total * 100
print(f"\nInterpretación del canal {nombre_canal}:")
for val, p in zip(valores, porcentajes):
print(f" - {val}: {p:.2f}%")
# Análisis simple basado en predominio
dominante = valores[np.argmax(conteo)]
if dominante == "Claro":
print(f">>> El canal {nombre_canal} muestra una imagen luminosa en este color.")
elif dominante == "Medio":
print(f">>> El canal {nombre_canal} es equilibrado, sin extremos marcados.")
else:
print(f">>> El canal {nombre_canal} tiende a tonos oscuros y apagados.")
print("\n" + "-"*50 + "\n")
# Ejecutar para cada canal
graficos_y_analisis(b_cat, "Azul")
graficos_y_analisis(g_cat, "Verde")
graficos_y_analisis(r_cat, "Rojo")
Interpretación del canal Azul: - Claro: 13.73% - Medio: 77.98% - Oscuro: 8.29% >>> El canal Azul es equilibrado, sin extremos marcados. --------------------------------------------------
Interpretación del canal Verde: - Claro: 33.49% - Medio: 52.32% - Oscuro: 14.19% >>> El canal Verde es equilibrado, sin extremos marcados. --------------------------------------------------
Interpretación del canal Rojo: - Claro: 9.18% - Medio: 52.68% - Oscuro: 38.14% >>> El canal Rojo es equilibrado, sin extremos marcados. --------------------------------------------------
fig, axes = plt.subplots(3, 2, figsize=(10, 12))
canales = [b_cat, g_cat, r_cat]
nombres = ["Azul", "Verde", "Rojo"]
for i, (categorias, nombre) in enumerate(zip(canales, nombres)):
valores, conteo = np.unique(categorias, return_counts=True)
total = conteo.sum()
porcentajes = conteo / total * 100
# Gráfico de torta
ax_pie = axes[i, 0]
ax_pie.pie(conteo, labels=valores, autopct="%1.1f%%")
ax_pie.set_title(f"Distribución - Canal {nombre}")
# Gráfico de barras
ax_bar = axes[i, 1]
ax_bar.bar(valores, conteo)
ax_bar.set_title(f"Conteo - Canal {nombre}")
ax_bar.set_xlabel("Categoría")
ax_bar.set_ylabel("Cantidad de píxeles")
plt.tight_layout()
plt.show()
La imagen evidencia que, al clasificar los píxeles por intensidad en tres categorías (Claro, Medio y Oscuro), predomina claramente la categoría Medio en los tres canales RGB, lo que sugiere una imagen con brillo general mayormente intermedio y sin saturaciones extremas; este patrón es especialmente fuerte en el canal azul, donde “Medio” concentra cerca del 78% y los valores oscuros son bajos (~8%), indicando poca presencia de azules intensamente apagados o muy brillantes. En el canal verde la distribución es más equilibrada, con una proporción importante de “Claro” (~33.5%) además de “Medio” (~52.3%), lo cual apunta a zonas con componente verde relativamente alta (áreas más iluminadas o con tonalidades verdosas). En contraste, el canal rojo mantiene “Medio” como mayoritario (~52.7%) pero muestra una fracción elevada de “Oscuro” (~38.1%) y pocos “Claro” (~9.2%), lo que sugiere que muchas regiones tienen componente roja baja (sombras o ausencia de rojos brillantes), reforzando una composición cromática dominada por tonos medios con variación marcada entre canales.
# !jupyter nbconvert --to html "Tarea2.ipynb"
# !jupyter nbconvert --to slides "Tarea2.ipynb"